<?php

/**
 * @package SimpleSiteInstaller
 * @author  Zanuda
**/

class Installer
{
	const DEFAULT_FORM = 'form';

	protected $sTitle = null;
	protected $sFormAction = null;

	protected $aColumns = array();
	protected $aFields = array();
	protected $aTemplates = array();
	protected $aVariables = array();

	public function __construct($sTitle = 'Инсталлятор')
	{
		session_start();
		foreach($_POST as $sKey => $mValue){
			if(!empty($mValue))
			{
				$this->SetSessionVar($sKey, $mValue);
			}
		}
		$this->sTitle = $sTitle;
	}

	protected function SetSessionVar($sKey, $mValue)
	{
		$_SESSION[$sKey] = serialize($mValue);
		return true;
	}

	protected function GetSessionVar($sKey, $mDefault = null)
	{
		return array_key_exists($sKey, $_SESSION) ? unserialize($_SESSION[$sKey]) : $mDefault;
	}

	public function SetColumns($aColumns)
	{
		$this->aColumns = array();
		foreach($aColumns as $mKey => $sTitle)
			$this->aColumns[$mKey]['title'] = $sTitle;
	}

	public function SetFormAction($sFormAction)
	{
		$this->sFormAction = $sFormAction;
	}

	public function AddField($sName, $sLabel, $sTag, $mColumn = 0, $bRequired = true, $bCheckPost = false)
	{
		$aField = array();
		$aField['name']   = $sName;
		$aField['label']  = $sLabel;
		$aField['tag']    = $sTag;
		$aField['post']   = $bCheckPost;
		$aField['checks'] = $bRequired ? array(array('FieldRequired', 'Это поле надо заполнить')) : array();
		$aField['error']  = array();
		$this->aFields[$sName] = $aField;
		$this->aColumns[$mColumn]['fields'][] = $sName;
	}

	public function AddCheck($sName, $sCallback, $sError)
	{
		$this->aFields[$sName]['checks'][] = array($sCallback, $sError);
	}

	public function Check()
	{
		$bOutput = false;
		foreach($this->aFields as $aField)
		{
			if(!count($aField['checks']))
				continue;
			foreach($aField['checks'] as $aCheck)
			{
				$sArg = (true == $aField['post']) ? $_POST[$aField['name']] : $this->GetSessionVar($aField['name']);
				if(call_user_func($aCheck['0'], $sArg))
				{
					$bOutput = true;
					$this->aFields[$aField['name']]['error'][] = $aCheck['1'] . ';';
				}
			}
		}
		return $bOutput;
	}

	public function DisplayForm($sForm = self::DEFAULT_FORM)
	{
		$sColumns = '';
		foreach($this->aColumns as $aColumn)
		{
			if(empty($aColumn['fields']))
				continue;
			$sFields = '';
			foreach($aColumn['fields'] as $sName)
			{
				$aField = $this->aFields[$sName];
				$this->Assign('label', $aField['label']);
				$this->Assign('name',  $aField['name']);
				$this->Assign('value', $this->GetSessionVar($sName));
				$this->Assign('error', implode('<br>', $aField['error']));
				$sFields .=  $this->Fetch('fields/' . $aField['tag']);
			}
			$this->Assign('title', $aColumn['title']);
			$this->Assign('fields', $sFields);
			$sColumns .=  $this->Fetch('column');
		}
		$this->Assign('form_action', $this->sFormAction);
		$this->Assign('columns', $sColumns);
		$sContent =  $this->Fetch($sForm);
		$this->Assign('title', $this->sTitle);
		$this->Assign('content', $sContent);
		$sOutput =  $this->Fetch('layout');
		echo $sOutput;
	}

	public function Get($sName)
	{
		return $this->GetSessionVar($sName);
	}

	public function Assign($sName, $sValue)
	{
		$this->aVariables['__' . strtoupper($sName) . '__'] = $sValue;
	}

	protected function Fetch($sTemplate)
	{
		if(empty($this->aTemplates[$sTemplate]))
			$this->aTemplates[$sTemplate] = file_get_contents(dirname(__FILE__) . '/templates/' . $sTemplate . '.tpl');
		return str_replace(array_keys($this->aVariables), array_values($this->aVariables), $this->aTemplates[$sTemplate]);
	}

	public function Install($sCallback)
	{
		$aArgs = array();
		foreach($_SESSION as $sKey => $mValue)
			$aArgs[$sKey] = $this->GetSessionVar($sKey);
		return call_user_func($sCallback, $aArgs);
	}
}

function FieldRequired($mValue)
{
	return empty($mValue);
}

?>